from flask import render_template, g, redirect, url_for, request, jsonify, session, current_app, abort

from info import response_code, db, constants
from info.models import Category, News, User
from info.utils.comment import user_login_data
from info.utils.file_storage import upload_file
from . import user_blue






@user_blue.route('/other_info')
@user_login_data
def other_info():
    '''其他用户概况'''
    # 1.用户信息
    login_user = g.user
    if not login_user:
        return redirect(url_for('index.index'))


    #2.获取用户登录信息
    other_id = request.args.get('user_id')
    if not other_id:
        abort(404)
    #3.查询要展示的被关注用户信息
    other = None
    try:
        other = User.query.get(other_id)
    except Exception as e:
        current_app.logger.error(e)
        abort(404)
    if not other:
        abort(404)

    #判断关注和取消关注的显示
    is_followed = False
    if login_user and other:
        if other in login_user.followed:
            is_followed = True

    context ={
        'user':login_user.to_dict(),
        'other': other.to_dict(),
        'is_followed':is_followed
    }


    return render_template('news/other.html',context=context)




@user_blue.route('/user_followed')
@user_login_data
def user_followed():

    '''我的关注'''
    # 1.用户信息
    login_user = g.user
    if not login_user:
        return redirect(url_for('index.index'))

    #2.接收参数
    page = request.args.get('p', '1')
    #3.效验参数
    try:
        page = int(page)

    except Exception as e:
        current_app.logger.error(e)
        page = '1'
    # 4.分页查询
    followed_user_list = []
    current_page = 1
    total_page = 1
    try:

        paginate = login_user.followed.paginate(page, constants.USER_FOLLOWED_MAX_COUNT, False)
        followed_user_list = paginate.items
        current_page = paginate.page
        total_page = paginate.pages
    except Exception as e:
        current_app.logger.error(e)
    # 5.构造渲染模板
    followed_dict_list = []
    for followed_user in followed_user_list:
        followed_dict_list.append(followed_user.to_dict())
    context = {
        'users': followed_user_list,
        'current_page': current_page,
        'total_page': total_page

    }


    #5.返回响应


    return render_template('news/user_follow.html', context=context)





@user_blue.route('/news_list')
@user_login_data
def news_list():
    '''新闻列表'''
    # 1.用户信息
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2.接收参数
    page = request.args.get('p', '1')

    # 3.效验参数
    try:
        page = int(page)

    except Exception as e:
        current_app.logger.error(e)
        page = '1'
    # 4.分页查询
    news_list = []
    current_page = 1
    total_page = 1
    try:

        paginate = News.query.filter(News.user_id == user.id).paginate(page, constants.USER_COLLECTION_MAX_NEWS, False)
        news_list = paginate.items
        current_page = paginate.page
        total_page = paginate.pages
    except Exception as e:
        current_app.logger.error(e)
    # 5.构造渲染模板
    news_dict_list = []

    for news in news_list:
        news_dict_list.append(news.to_review_dict())
    context = {
        'news_list': news_dict_list,
        'current_page': current_page,
        'total_page': total_page

    }

    # 6.响应模板
    return render_template('news/user_news_list.html', context=context)


@user_blue.route('/news_release', methods=['GET', 'POST'])
@user_login_data
def news_release():
    '''新闻发布'''
    # 1.用户登录信息
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2.GET请求
    if request.method == 'GET':
        # 2.1渲染模板
        categories = []
        try:
            categories = Category.query.all()
        except Exception as e:
            current_app.logger.error(e)

        # 删除最新分类
        categories.pop(0)

        context = {
            'categories': categories
        }
        return render_template('news/user_news_release.html', context=context)

    # 3.
    if request.method == 'POST':
        # 3.1接收参数
        title = request.form.get("title")
        source = "个人发布"
        digest = request.form.get("digest")
        content = request.form.get("content")
        index_image = request.files.get("index_image")
        category_id = request.form.get("category_id")

        # 3.2效验参数
        if not all([title, source, digest, content, index_image, category_id]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')

        # 3.3读取用户上传的图片信息
        try:
            index_image_data = index_image.read()
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')

        # 3.4上传到七牛云
        try:
            key = upload_file(index_image_data)
        except Exception as e:
            current_app.logger.error(e)
            return jsonify(errno=response_code.RET.THIRDERR, errmsg='上传图片失败')

        # 3.5创建新闻类模型对象,对属性赋值并添加到数据库
        news = News()
        news.title = title
        news.digest = digest
        news.source = source
        news.content = content
        news.index_image_url = constants.QINIU_DOMIN_PREFIX + key
        news.category_id = category_id
        news.user_id = user.id
        # 1代表待审核状态
        news.status = 1

        try:
            db.session.add(news)
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=response_code.RET.DBERR, errmsg='保存新闻发布数据失败')

        # 3.6响应发布结果
        return jsonify(errno=response_code.RET.OK, errmsg='发布新闻成功')


@user_blue.route('/user_collection')
@user_login_data
def user_collection():
    '''展示用户收藏
    1.用户登录信息
    2.接收参数
    3.效验参数
    4.分页查询
    5.构造渲染模板数据
    6.响应渲染模板
    '''
    # 1.
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2
    page = request.args.get('p', '1')
    # 3.
    try:
        page = int(page)
    except Exception as e:
        current_app.logger.error(e)
        page = '1'
    # 4.
    paginate = None
    try:
        paginate = user.collection_news.paginate(page, constants.USER_COLLECTION_MAX_NEWS, False)
    except Exception as e:
        current_app.logger.error(e)
    # 5构造响应的模板数据

    news_list = paginate.items
    current_page = paginate.page
    total_page = paginate.pages

    news_dict_list = []

    for news in news_list:
        news_dict_list.append(news.to_basic_dict())
    # 6.
    context = {
        'news_list': news_dict_list,
        'current_page': current_page,
        'total_page': total_page
    }

    return render_template('news/user_collection.html', context=context)


@user_blue.route('/pass_info', methods=['GET', 'POST'])
@user_login_data
def pass_info():
    '''密码修改
    1.判断用户登录信息
    2.GET请求逻辑
    3.POST请求逻辑
    3.1接收参数(新旧密码)
    3.2效验参数(是否完整,旧密码是否我原先的密码
    3.3更新密码
    3.4提交数据库
    3.5响应修改成功

    '''
    # 1.
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2.
    if request.method == 'GET':
        context = {
            'user': user
        }
        return render_template('news/user_pass_info.html', context=context)
    # 3.
    if request.method == 'POST':
        # 3.1接受参数
        old_password = request.json.get('old_password')
        new_password = request.json.get('new_password')
        # 3.2效验参数,是否完整,是否与我的密码相等
        if not all([old_password, new_password]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')

        if not user.check_passowrd(old_password):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='原密码输入有误')
        # 3.3更新密码
        user.password = new_password

        # 3.4提交到数据库
        try:
            db.session.commit()
        except Exception as e:
            db.session.rollback()
            current_app.logger.error(e)
            return jsonify(errno=response_code.RET.DBERR, errmsg='保存修改后密码有误')
        # 3.5
        return jsonify(errno=response_code.RET.OK, errmsg='保存密码成功')


@user_blue.route('/pic_info', methods=['GET', 'POST'])
@user_login_data
def pic_info():
    '''头像设置'''
    # 1.用户是否存在
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2.实现GET请求
    if request.method == 'GET':
        context = {
            'user': user.to_dict()

        }

        return render_template('news/user_pic_info.html', context=context)

    # 3.实现POST请求,修改用户信息
    if request.method == 'POST':
        #         3.1获取参数(图片)
        avatar_file = request.files.get('avatar')

    #         3.2效验参数(图片)
    try:
        avatar_data = avatar_file.read()
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='读取头像数据失败')

    #         3.3调用上传的方法,将图片上传到七牛
    try:
        key = upload_file(avatar_data)
    except Exception as e:
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.PARAMERR, errmsg='上传失败')

        #       3.4保存用户头像的key到数据库
    user.avatar_url = key
    try:
        db.session.commit()
    except Exception as e:
        db.session.rollback()
        current_app.logger.error(e)
        return jsonify(errno=response_code.RET.DBERR, errmsg='保存用户头像失败')

    data = {
        'avatar_url': constants.QINIU_DOMIN_PREFIX + key
    }

    #       3.5响应头像上传结果
    return jsonify(errno=response_code.RET.OK, errmsg='ok', data=data)


@user_blue.route('/base_info', methods=['GET', 'POST'])
@user_login_data
def base_info():
    '''基本资料'''
    # 1.用户是否存在
    user = g.user
    if not user:
        return redirect(url_for('index.index'))
    # 2.实现GET请求
    if request.method == 'GET':
        context = {
            'user': user.to_dict()

        }

        return render_template('news/user_base_info.html', context=context)
    # 3.实现POST请求,修改用户信息
    if request.method == 'POST':
        #         3.1.接收参数(签名,昵称,性别)
        nick_name = request.json.get('nick_name')
        signature = request.json.get('signature')
        gender = request.json.get('gender')

        # 3.2判断参数是否完整,性别是否在指定范围
        if not all([nick_name, signature, gender]):
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='缺少参数')
        if gender not in ['MAN', 'WOMAN']:
            return jsonify(errno=response_code.RET.PARAMERR, errmsg='参数错误')

            # 3.3.修改用户信息
        user.signature = signature
        user.nick_name = nick_name
        user.gender = gender

        try:
            db.session.commit()
        except Exception as e:
            current_app.logger.error(e)
            db.session.rollback()
            return jsonify(errno=response_code.RET.DBERR, errmsg='添加数据失败')

        # 4/修改昵称后记得把用户保持信息修改
        session['niack_name'] = nick_name

        # 5.响应修改结果
        return jsonify(errno=response_code.RET.OK, errmsg='OK')


@user_blue.route('/info')
@user_login_data
def user_info():
    user = g.user
    if not user:
        return redirect(url_for('index.index'))

    context = {
        'user': user.to_dict()

    }

    return render_template('news/user.html', context=context)
